
package org.movee.spring.data.hugegraph.repository.query;

import org.movee.spring.data.hugegraph.gremlin.GremlinTraversal;
import org.movee.spring.data.hugegraph.query.HugeOperations;
import org.movee.spring.data.hugegraph.query.paramerter.HugeParameterAccessor;
import org.movee.spring.data.hugegraph.query.paramerter.HugeParametersParameterAccessor;
import lombok.NonNull;
import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.data.repository.query.ResultProcessor;

public abstract class AbstractHugeRepositoryQuery implements RepositoryQuery {

    private final HugeQueryMethod method;
    private final HugeOperations operations;
    private final QueryHugeTraversalCreator queryHugeTraversalCreator;

    public AbstractHugeRepositoryQuery(@NonNull HugeQueryMethod method, @NonNull HugeOperations operations) {
        this.method = method;
        this.operations = operations;
        this.queryHugeTraversalCreator = new QueryHugeTraversalCreator(method,
                operations.getConverter().getMappingContext());
    }

    protected abstract GremlinTraversal createQuery(HugeParameterAccessor accessor);

    protected boolean isDeleteQuery() {
        return false;
    }

    @Override
    public Object execute(Object[] parameters) {
        final HugeParameterAccessor accessor = new HugeParametersParameterAccessor(this.method, parameters);

        final GremlinTraversal query = this.createQuery(accessor);
        final ResultProcessor processor = method.getResultProcessor().withDynamicProjection(accessor);
        final HugeQueryExecution execution = this.getExecution();

        return execution.execute(query, processor.getReturnedType().getReturnedType());
    }

    @Override
    public HugeQueryMethod getQueryMethod() {
        return this.method;
    }

    protected HugeOperations getOperations() {
        return this.operations;
    }

    protected QueryHugeTraversalCreator getQueryHugeTraversalCreator() {
        return this.queryHugeTraversalCreator;
    }


    private HugeQueryExecution getExecution() {

        if (getQueryMethod().isCollectionQuery()) {
            return new HugeQueryExecution.CollectionExecution(getOperations());
        } else {
            return new HugeQueryExecution.SingleEntityExecution(getOperations(), true);
        }
    }





}
